<?php
/* -------------------------------------------------------------------------------------
* 	ID:						$Id: class.clickandbuy.php 135 2013-09-22 07:30:55Z phone.mueller@googlemail.com $
* 	Letzter Stand:			$Revision: 135 $
* 	zuletzt geaendert von:	$Author: peter $
* 	Datum:					$Date: 2013-09-22 07:30:55 +0000 (Sun, 22 Sep 2013) $
*
* 	SEO:mercari by Siekiera Media
* 	http://www.seo-mercari.de
*
* 	Copyright © since 2011 SEO:mercari
* --------------------------------------------------------------------------------------
* 	based on:
* 	© 2000-2001 The Exchange Project  (earlier name of osCommerce)
* 	© 2002-2003 osCommerce - www.oscommerce.com
* 	© 2003     nextcommerce - www.nextcommerce.org
* 	(c) 2005     xt:Commerce - www.xt-commerce.com
*
* 	Released under the GNU General Public License
* ----------------------------------------------------------------------------------- */

include(DIR_FS_CATALOG.'callback/pi_clickandbuy/lib/nusoap.php');

define('AUTH_MERCHANT_ID', MODULE_PAYMENT_PI_CLICKANDBUY_MERCHANT_ID);
define('AUTH_PROJECT_ID', MODULE_PAYMENT_PI_CLICKANDBUY_PROJECT_ID);
define('AUTH_SECRETKEY_ID', MODULE_PAYMENT_PI_CLICKANDBUY_SECRET_KEY);

class clickandbuy extends nusoap_client {

	var $SOAP_ENDPOINT;
	var $SOAP_NAMESPACE;
	var $SOAP_ACTION;
	var $MMS_LOG = false;
	var $MMS_EMAIL_TO;
	var $MMS_EMAIL_FROM;
	var $returnURL;
	var $auth = array();
	var $paymentType;
	
	function __construct($sandbox = true) {
		if(!$sandbox)
			$this->SOAP_ENDPOINT = 'https://api.clickandbuy.com/webservices/soap/pay_1_0_0';
		else	
			$this->SOAP_ENDPOINT = 'https://api.clickandbuy-s1.com/webservices/soap/pay_1_0_0';
		
		$this->SOAP_NAMESPACE = 'http://api.clickandbuy.com/webservices/pay_1_0_0/" xmlns="http://api.clickandbuy.com/webservices/pay_1_0_0/';
		
		$this->SOAP_ACTION = 'http://api.clickandbuy.com/webservices/pay_1_0_0/';
		
		$this->paymentType = 'clickandbuy';
		
		if(CHECKOUT_AJAX_STAT == 'true')
			$this->returnURL = FILENAME_CHECKOUT;
		else
			$this->returnURL = FILENAME_CHEKOUT_PAYMENT;
	}
	
	function doTrans() {
		global $price, $order, $db;
		
		$cseoID = session_id();
	
		$shipping_tax_rate = $this->get_shipping_tax_rate($order);
		
		if ($_SESSION['customers_status']['customers_status_show_price_tax'] == 0 && $_SESSION['customers_status']['customers_status_add_tax_ot'] == 1)
			$basketAmount = $order->info['total'] + $order->info['tax'];
		else
			$basketAmount = $order->info['total'];
		
		$basketAmount = round($price->CalculateCurrEx($basketAmount, $_SESSION['currency']), $price->get_decimal_places($_SESSION['currency']));	
		
		//Shop has tax class in shipping module add shipping tax to order total 
		if ($shipping_tax_rate > 0) {
			$shipping_tax = round(($order->info ['shipping_cost'] / 100) * $shipping_tax_rate,2);
			$basketAmount = ($basketAmount + $shipping_tax);	
		} 
		
		$basketAmount = number_format ($basketAmount, 2, '.', '' );
		$currency = $_SESSION['currency'];
		$customer_id = $_SESSION['customer_id'];
		
		$authentication = $this->getCabSettings($this->paymentType);
		$secretKey = AUTH_SECRETKEY_ID;
		
		$details = array();
		$shippingAddress = array();
		$billingAddress = array();
		$items = array();
		$recurring = array();
	
		$debited = $basketAmount;
		$authorization = 0;
				
		//Text for shipping costs
		$shippingCostsText = utf8_encode(MODULE_PAYMENT_PI_CLICKANDBUY_SHIPPING_COSTS_TEXT);
		
		//Create a new externalID avoid reload problem or double call 
	  	$externalID = substr(md5(uniqid(rand())),0,12);  
		$sHash = $this->generateSHash($basketAmount,$currency,$externalID,AUTH_SECRETKEY_ID,$this->paymentType);	    					
	
		//successURL and failureURL
		$shopURL = (ENABLE_SSL ? HTTPS_SERVER . DIR_WS_CATALOG : HTTP_SERVER . DIR_WS_CATALOG);		
		$successURL = $shopURL."pi_clickandbuy_trans.php?externalID=".$externalID."&sHash=".$sHash."&paymentType=".$this->paymentType;				
		$failureURL = $shopURL.$this->returnURL."?cseoID=".$cseoID;				
					
		$consumerIPAddress = $_SERVER['REMOTE_ADDR']; 	
		$consumerLanguage = $this->getConsumerLanguage();
		$consumerCountry = strtolower($order->customer['country']['iso_code_2']);
	
		$details['amount'] = $basketAmount;
		$details['currency'] = $currency;	
		$details['successURL'] = $successURL;
		$details['failureURL'] = $failureURL;
		$details['consumerIPAddress'] = $consumerIPAddress;
		$details['externalID'] = $externalID;
		$details['consumerLanguage'] = $consumerLanguage;
		$details['consumerCountry'] = $consumerCountry;				
		$details['orderDescription'] = utf8_encode(CLICKANDBUY_CHECKOUT_ORDER_DESCRIPTION.STORE_NAME);		
				
		//Shipping details	
		if(empty($_POST['shippingCompany'])) {
			$shippingType = 'consumer';
			$shippingAddress['firstName'] = utf8_encode($order->delivery['firstname']);
			$shippingAddress['lastName'] = utf8_encode($order->delivery['lastname']);
				
		} else {
			$shippingType = 'company';
			$shippingAddress['name'] = utf8_encode($order->delivery['company']);
		}
		
		$shippingAddress['address']['street'] = utf8_encode($order->delivery['street_address']);
		$shippingAddress['address']['zip'] = $order->delivery['postcode'];
		$shippingAddress['address']['city'] = utf8_encode($order->delivery['city']);
		$shippingAddress['address']['country'] = strtolower($order->delivery['country']['iso_code_2']);
				
		//Billing details	
		if(empty($order->billing['company'])) {
			$billingType = 'consumer';
			$billingAddress['firstName'] = utf8_encode($order->billing['firstname']);
			$billingAddress['lastName'] = utf8_encode($order->billing['lastname']);
		} else {
			$billingType = 'company';
			$billingAddress['name'] = $order->billing['company'];
		}
		
		$billingAddress['address']['street'] =  utf8_encode($order->billing['street_address']);
		$billingAddress['address']['zip'] = $order->billing['postcode'];
		$billingAddress['address']['city'] = utf8_encode($order->billing['city']);
		$billingAddress['address']['country'] = strtolower($order->billing['country']['iso_code_2']);
		
		$items[1]['itemType'] = 'item1Text';
		$items[1]['textItemDescription'] = utf8_encode(CLICKANDBUY_CHECKOUT_ORDER_DESCRIPTION.STORE_NAME);
	
		$items = $this->getItems($currency);
		
		$billingAddress = '';
		$shippingAddress = '';
		$recurring = '';
		
		$requestResult = $this->payRequest($details,$shippingType,$shippingAddress,$billingType,$billingAddress,$items,$recurring,$inc);
	
		$payRequest = $requestResult['values'];
		$transactionID = $payRequest['transaction']['transactionID'];
		$transactionStatus = $payRequest['transaction']['transactionStatus'];
		$redirectURL = $payRequest['transaction']['redirectURL'];  			
		empty($payRequest['transaction']['createdRecurringPaymentAuthorization']['recurringPaymentAuthorizationID']) ? $authorizationID = 'NULL' : $authorizationID = $payRequest['transaction']['createdRecurringPaymentAuthorization']['recurringPaymentAuthorizationID'];
	
		$db->db_query("INSERT INTO ".DB_PREFIX."picab_orders (id,shopOrderID,shopUserID,transactionID,externalID,paymentType,authorization,authorizationID,handshake,closed,recAmount,amount,debited,refunded,cancelled,currency,created,modified) VALUES (NULL,'', '".$customer_id."', '".$transactionID."','".$externalID."','".$this->paymentType."','".$authorization."','".$authorizationID."',0,0,'".$recAmount."','".$basketAmount."','".$debited."',0.00,0.00,'".$currency."','".date("Y-m-d H:i:s")."','".date("Y-m-d H:i:s")."')");
		
		return $redirectURL;
	}
	
	function doSoapRequest($reqName,$reqParam,$inc=true,$client=null) {	
	
		$client = new nusoap_client($this->SOAP_ENDPOINT);	
		$client->soap_defencoding = "UTF-8";
		$success = false;
		$result = $client->call($reqName, $reqParam, $this->SOAP_NAMESPACE, $this->SOAP_ACTION, false, null, "rpc", "literal");
	
		if ($client->fault) {
			$nusoapResult['error_type'] = 'fault';		
			$nusoapResult['faultcode'] = $client->faultcode;
			$nusoapResult['faultstring'] = $client->faultstring;
			$nusoapResult['faultdetail'] = $client->fault_detail;
	
		} elseif($client->getError()) {
			$nusoapResult['error_type'] = 'error';
			$nusoapResult['error'] = $client->getError();		
		
		} else
			$success = true;
	
		$nusoapResult['success'] = $success;
		$nusoapResult['values'] = $result;		
		$nusoapResult['req_name'] = $reqName;
		$nusoapResult['request'] = $client->request;
		$nusoapResult['response'] = $client->response;
		
		return $nusoapResult; 
	}
	
	function generateToken($projectID, $secretKey) {
		$timestamp = gmdate("YmdHis");	
		$hashStr = $projectID."::".$secretKey."::".$timestamp;
		$toBeHashed = strtoupper(sha1($hashStr));	
		$token = $timestamp.'::'.$toBeHashed; 	
		
		return $token;	
	}
	
	function removeEmptyTag($arr) {
		if(!empty($arr)) {
			foreach ($arr as $key => $value) {
				if(is_array($arr[$key])) {
					foreach ($arr[$key] as $key2 => $value2) {
						if (empty($arr[$key][$key2])) {    	
							unset($arr[$key][$key2]);
						}   	  			
					}    	
				}     
				if (empty($arr[$key]))    	
					unset($arr[$key]);
			} 
			return $arr;
		}
	}
	
	function createItemList($items) {
		
		// Fill itemListArr
		$itemListArr = array ();
	  foreach ($items as $key => $value) {
	  	$item = 'item'.$key;
			if($value['itemType'] == $item.'Text') {
				array_push($itemListArr,new soapval('item',false,array('itemType' => 'TEXT','description' => $value['textItemDescription'])));					    	
			} elseif($value['itemType'] == $item.'Item') {
				array_push($itemListArr,
					new soapval('item',false,
							array('itemType' => 'ITEM',
								'description' => $value['itemDescription'],
								'quantity' => $value['itemQuantity'],
								new soapval('unitPrice',false,array('amount' => $value['itemUnitPriceAmount'],'currency' => $value['itemUnitPriceCurrency'])),
								new soapval('totalPrice',false,array('amount' => $value['itemTotalPriceAmount'],'currency' => $value['itemTotalPriceCurrency']))
							)
					)
				);				
			} elseif($value['itemType'] == $item.'Subtotal') {
				array_push($itemListArr,
					new soapval('item',false,
							array('itemType' => 'SUBTOTAL',
								'description' => $value['subtotalItemDescription'],
								new soapval('totalPrice',false,array('amount' => $value['subtotalItemTotalPriceAmount'],'currency' => $value['subtotalItemTotalPriceCurrency']))
							)
					)
				);				
			} elseif($value['itemType'] == $item.'Vat') {
				array_push($itemListArr,
					new soapval('item',false,
							array('itemType' => 'VAT',
								'description' => $value['vatItemDescription'],
								new soapval('totalPrice',false,array('amount' => $value['vatItemTotalPriceAmount'],'currency' => $value['vatItemTotalPriceCurrency']))
							)
					)
				);				
			} elseif($value['itemType'] == $item.'Total') {
				array_push($itemListArr,
					new soapval('item',false,
							array('itemType' => 'TOTAL',
								'description' => $value['totalItemDescription'],
								new soapval('totalPrice',false,array('amount' => $value['totalItemTotalPriceAmount'],'currency' => $value['totalItemTotalPriceCurrency']))
							)
					)
				);				
			}
	  }	
	  return $itemListArr;	
	}
	
	function payRequest($details,$shippingType,$shippingAddress,$billingType,$billingAddress,$items,$createRecurring,$inc=true) {				
						
		$token = $this->generateToken(AUTH_PROJECT_ID,AUTH_SECRETKEY_ID);
		
		$amountArr = array(
			'amount' => $details['amount'],
			'currency' => $details['currency']
		);	
	
		$shippingAddressArr = array(
			$shippingType => $shippingAddress
		);	
		
		$billingAddressArr = array(
			$billingType => $billingAddress
		);	
				
		$itemListArr = array();
		if(!empty($items))			
			$itemListArr = $this->createItemList($items);		
		
		$orderDetailsArr = array(
			'text' => $details['orderDescription'],
			'itemList' => $itemListArr
		);	
	
		$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
		$createRecurring = $this->removeEmptyTag($createRecurring);
		
		$detailsArr = array(
			'amount' => $amountArr,
			'basketRisk' => $details['basketRisk'],
			'clientRisk' => $details['clientRisk'],
			'authExpiration' => $details['authExpiration'],
			'confirmExpiration' => $details['confirmExpiration'],
			'successExpiration' => $details['successExpiration'],
			'successURL' => $details['successURL'],
			'failureURL' => $details['failureURL'],
			'consumerIPAddress' => $details['consumerIPAddress'],
			'externalID' => $details['externalID'],
			'consumerLanguage' => $details['consumerLanguage'],
			'consumerCountry' => $details['consumerCountry'],	
			'orderDetails' => $orderDetailsArr,	
			'shipping' => $shippingAddressArr,	
			'billing' => $billingAddressArr,	
			'createRecurring' => $createRecurring		
		);	
				
		$detailsArr = $this->removeEmptyTag($detailsArr);
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
					
	 	$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);
		
		#echo '<pre>';
		#print_r($reqParam); 
		#echo '</pre>'; exit;
				
		$nusoapResult = $this->doSoapRequest('payRequest_Request',$reqParam,false,$client);
				
		return $nusoapResult;	
	}
	
	function payRequestRecurring($details,$shippingType,$shippingAddress,$billingType,$billingAddress,$items) {				
		$client = new nusoap_client($this->SOAP_ENDPOINT);
		
		$token = $this->generateToken(AUTH_PROJECT_ID,AUTH_SECRETKEY_ID);
		
		$amountArr = array(
			'amount' => $details['amount'],
			'currency' => $details['currency']
		);	
		
		$shippingAddressArr = array(
			$shippingType => $shippingAddress
		);	
		
		$billingAddressArr = array(
			$billingType => $billingAddress
		);
		
		$itemListArr = array();
		if(!empty($items)) {		
			$itemListArr = $this->createItemList($items);		
		}
			
		$orderDetailsArr = array(
			'text' => $details['orderDescription'],
			'itemList' => $itemListArr
		);	
	
		$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
			
		$detailsArr = array(
			'amount' => $amountArr,
			'recurringPaymentAuthorizationID' => $details['recurringAuthorizationID'],	
			'basketRisk' => $details['basketRisk'],
			'clientRisk' => $details['clientRisk'],
			'externalID' => $details['externalID'],
			'authExpiration' => $details['authExpiration'],	
			'successExpiration' => $details['successExpiration'],
			'orderDetails' => $orderDetailsArr,	
			'shipping' => $shippingAddressArr,	
			'billing' => $billingAddressArr,		
		);	
			
		$detailsArr = $this->removeEmptyTag($detailsArr);
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
					
	 	$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);
		 		 	
		$nusoapResult = $this->doSoapRequest('payRequestRecurring_Request', $reqParam, false, $client);
		return $nusoapResult;		
	}
	
	function refundRequest($authentication,$details,$items) {	
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
			);		
	
		$amountArr = array(
			'amount' => $details['amount'],
			'currency' => $details['currency']
		);			
		
		$itemListArr = array();
		if(!empty($items)) {		
			$itemListArr = $this->createItemList($items);		
		}
		
		$orderDetailsArr = array(
			'itemList' => $itemListArr
		);	
	
		$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
		  	
		$detailsArr = array(
			'amount' => $amountArr,
			'transactionID' => $details['transactionID'],
			'externalID' => $details['externalID'],
			'orderDetails' => $orderDetailsArr
		);
		
		$detailsArr = $this->removeEmptyTag($detailsArr);
		
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);	
	 				
		$nusoapResult = $this->doSoapRequest('refundRequest_Request',$reqParam,false,$client);
		return $nusoapResult;		
	}
	
	function cancelRequest($authentication,$transactionID) {		
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
	
		$detailsArr = array(
			'transactionID' => $transactionID
		);
		
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);		
			
		$nusoapResult = $this->doSoapRequest('cancelRequest_Request',$reqParam);
		return $nusoapResult;		
	}
	
	function creditRequest($authentication,$details,$items) {
			
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
			);		
	
		$amountArr = array(
			'amount' => $details['amount'],
			'currency' => $details['currency']
		);			
		
		$itemListArr = array();
		if(!empty($items)) {		
			$itemListArr = $this->createItemList($items);		
		}
		
		$orderDetailsArr = array(
			'itemList' => $itemListArr
		);	
	
		$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
		  	
		$detailsArr = array(
			'amount' => $amountArr,
			'emailAddress' => $details['emailAddress'],
			'externalID' => $details['externalID'],
			'orderDetails' => $orderDetailsArr	
		);
		
		$detailsArr = $this->removeEmptyTag($detailsArr);
		
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);	
	 				
		$nusoapResult = $this->doSoapRequest('creditRequest_Request',$reqParam,false,$client);	
		return $nusoapResult;		
	}
	
	function statusRequest($authentication,$statusType,$ids) {	
		
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);	
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
			);		
	
		// Fill idListArr
		$pos=0;
	  foreach ($ids as $key => $value) {
	    if ($pos==0) {
				$idListArr = array(new soapval($statusType,false,$value));
	    } else {
				array_push($idListArr,new soapval($statusType,false,$value));					    	
	    }
	    $pos++;
		}		
		
		$detailsArr = array(
			$statusType.'List' => $idListArr
		);
			
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);	
	 		
		$nusoapResult = $this->doSoapRequest('statusRequest_Request',$reqParam,false,$client);
		return $nusoapResult;		
	}
	
	function createBatch($authentication,$externalBatchID) {	
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);	
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
	
		$detailsArr = array(
			'externalBatchID' => $externalBatchID
		);
		
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);		
			
		$nusoapResult = $this->doSoapRequest('createBatch_Request',$reqParam);	
		return $nusoapResult;	
	}
	
	function addBatchPayRequest($authentication,$batchID,$itemList) {			
		
		$client = new nusoap_client($this->SOAP_ENDPOINT);
		
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$pos = 0;
		$batchItems = array();
		foreach($itemList as $key => $itemArr) {
			$amountArr = array(
				'amount' => $itemArr['amount'],
				'currency' => $itemArr['currency']
			);	
			
			$shippingAddressArr = array(
				$itemArr['shippingType'] => $itemArr['shippingAddress']
			);	
			
			$billingAddressArr = array(
				$itemArr['billingType'] => $itemArr['billingAddress']
			);
					
			$amountLimitArr = array(
				'amount' => $itemArr['recurring']['amountLimit']['amount'],
				'currency' => $itemArr['recurring']['amountLimit']['currency']
			);	
			
			$amountLimitArr = $this->removeEmptyTag($amountLimitArr);
				
			$createRecurringArr = array(
				'description' => $itemArr['recurring']['description'],
				'numberLimit' => $itemArr['recurring']['numberLimit'],
				'amountLimit' => $amountLimitArr,
				'expireDate' => $itemArr['recurring']['expireDate'],		
				'revokableByConsumer' => $itemArr['recurring']['revokableByConsumer']
			);	
		
			$createRecurringArr = $this->removeEmptyTag($createRecurringArr);
			
			$items = $itemArr['itemDetailList'];	
			$itemListArr = array();
			if(!empty($items)) {		
				$itemListArr = $this->createItemList($items);		
			}
		
			$orderDetailsArr = array(
				'text' => $itemArr['orderDescription'],
				'itemList' => $itemListArr
			);	
		
			$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
			
			$payRequestArr = array(
				'amount' => $amountArr,
				'basketRisk' => $itemArr['basketRisk'],
				'clientRisk' => $itemArr['clientRisk'],
				'authExpiration' => $itemArr['authExpiration'],
				'confirmExpiration' => $itemArr['confirmExpiration'],
				'successExpiration' => $itemArr['successExpiration'],
				'successURL' => $itemArr['successURL'],
				'failureURL' => $itemArr['failureURL'],
				'consumerIPAddress' => $itemArr['consumerIPAddress'],
				'externalID' => $itemArr['externalID'],
				'consumerLanguage' => $itemArr['consumerLanguage'],
				'consumerCountry' => $itemArr['consumerCountry'],	
				'orderDetails' => $orderDetailsArr,	
				'shipping' => $shippingAddressArr,	
				'billing' => $billingAddressArr,	
				'createRecurring' => $createRecurringArr	
			);	
			
			$payRequestArr = $this->removeEmptyTag($payRequestArr);
			
			$batchItemDetail = array(new soapval('payRequestDetails',false,$payRequestArr));		
			array_push($batchItems,new soapval('batchItemDetails',false,array('externalID' => $itemArr['batchItemExternalID'],'details' => $batchItemDetail)));
		}
	
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
					
		$detailsArr = array(
			'batchID' => $batchID,
	 		'batchItemDetailsList' => $batchItems 		
		);
			
	 	$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr
	 	);
		 		 	
		$nusoapResult = $this->doSoapRequest('addBatchItem_Request',$reqParam,false,$client);	
		return $nusoapResult;	
	}
	
	function addBatchRecurring($authentication,$batchID,$itemList) {			
		
			
		
		$client = new nusoap_client($this->SOAP_ENDPOINT);
		
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$pos = 0;
		$batchItems = array();
		foreach($itemList as $key => $itemArr) {
			$amountArr = array(
				'amount' => $itemArr['amount'],
				'currency' => $itemArr['currency']
			);	
					
			$shippingAddressArr = array(
				$itemArr['shippingType'] => $itemArr['shippingAddress']
			);	
			
			$billingAddressArr = array(
				$itemArr['billingType'] => $itemArr['billingAddress']
			);
							
			$items = $itemArr['itemDetailList'];	
			$itemListArr = array();
			if(!empty($items)) {		
				$itemListArr = $this->createItemList($items);		
			}
		
			$orderDetailsArr = array(
				'text' => $itemArr['orderDescription'],
				'itemList' => $itemListArr
			);	
		
			$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
					
			$payRequestRecurringArr = array(
				'amount' => $amountArr,
				'recurringPaymentAuthorizationID' => $itemArr['recurringPaymentAuthorizationID'],
				'basketRisk' => $itemArr['basketRisk'],
				'clientRisk' => $itemArr['clientRisk'],
				'externalID' => $itemArr['externalID'],
				'successExpiration' => $itemArr['successExpiration'],		
				'orderDetails' => $orderDetailsArr,	
				'shipping' => $shippingAddressArr,	
				'billing' => $billingAddressArr
			);	
			
			$payRequestRecurringArr = $this->removeEmptyTag($payRequestRecurringArr);
			
			$batchItemDetail = array(new soapval('payRequestRecurringDetails',false,$payRequestRecurringArr));		
			array_push($batchItems,new soapval('batchItemDetails',false,array('externalID' => $itemArr['batchItemExternalID'],'details' => $batchItemDetail)));
		}
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
			);		
					
		$detailsArr = array(
			'batchID' => $batchID,
	 		'batchItemDetailsList' => $batchItems 		
			);
			
	 	$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr
	 	);
		 		 	
		$nusoapResult = $this->doSoapRequest('addBatchItem_Request',$reqParam,false,$client);	
		return $nusoapResult;	
	}
	
	function addBatchCredit($authentication,$batchID,$itemList) {			
		
			
		
		$client = new nusoap_client($this->SOAP_ENDPOINT);
		
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
	
		$pos = 0;
		$batchItems = array();
		foreach($itemList as $key => $itemArr) {
			$amountArr = array(
				'amount' => $itemArr['amount'],
				'currency' => $itemArr['currency']
			);	
				
			$items = $itemArr['itemDetailList'];	
			$itemListArr = array();
			if(!empty($items)) {		
				$itemListArr = $this->createItemList($items);		
			}
		
			$orderDetailsArr = array(
				'text' => $itemArr['orderDescription'],
				'itemList' => $itemListArr
			);	
		
			$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
			
			$requestArr = array(
				'amount' => $amountArr,
				'emailAddress' => $itemArr['emailAddress'],
				'consumerLanguage' => $itemArr['consumerLanguage'],
				'externalID' => $itemArr['externalID'],
			'orderDetails' => $orderDetailsArr
			);	
			
			$creditArr = $this->removeEmptyTag($requestArr);
			
			$batchItemDetail = array(new soapval('creditRequestDetails',false,$creditArr));		
			array_push($batchItems,new soapval('batchItemDetails',false,array('externalID' => $itemArr['batchItemExternalID'],'details' => $batchItemDetail)));		
		}
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
					
		$detailsArr = array(
			'batchID' => $batchID,
	 		'batchItemDetailsList' => $batchItems 		
		);
			
	 	$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr
	 	);
		 		 	
		$nusoapResult = $this->doSoapRequest('addBatchItem_Request',$reqParam,false,$client);	
		return $nusoapResult;	
	}
	
	function addBatchRefund($authentication,$batchID,$itemList) {			
		
			
		
		$client = new nusoap_client($this->SOAP_ENDPOINT);	
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$pos = 0;
		$batchItems = array();
		foreach($itemList as $key => $itemArr) {
			$amountArr = array(
				'amount' => $itemArr['amount'],
				'currency' => $itemArr['currency']
			);	
				
			$items = $itemArr['itemDetailList'];	
			$itemListArr = array();
			if(!empty($items)) {		
				$itemListArr = $this->createItemList($items);		
			}
		
			$orderDetailsArr = array(
				'text' => $itemArr['orderDescription'],
				'itemList' => $itemListArr
			);	
		
			$orderDetailsArr = $this->removeEmptyTag($orderDetailsArr);
											
			$requestArr = array(
				'amount' => $amountArr,
				'transactionID' => $itemArr['transactionID'],
				'orderDetails' => $orderDetailsArr,
				'externalID' => $itemArr['externalID']
			);	
			
			$refundArr = $this->removeEmptyTag($requestArr);
	
			$batchItemDetail = array(new soapval('refundRequestDetails',false,$refundArr));		
			array_push($batchItems,new soapval('batchItemDetails',false,array('externalID' => $itemArr['batchItemExternalID'],'details' => $batchItemDetail)));		
		}
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
					
		$detailsArr = array(
			'batchID' => $batchID,
	 		'batchItemDetailsList' => $batchItems 		
		);
			
	 	$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr
	 	);
		 		 	
		$nusoapResult = $this->doSoapRequest('addBatchItem_Request',$reqParam,false,$client);	
		return $nusoapResult;	
	}
	
	function addBatchCancel($authentication,$batchID,$itemList) {		
		
			
		
		$client = new nusoap_client($this->SOAP_ENDPOINT);		
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$pos = 0;
		$batchItems = array();
		foreach($itemList as $key => $itemArr) {							
			$requestArr = array(
				'transactionID' => $itemArr['transactionID']
			);	
			
			$cancelArr = $this->removeEmptyTag($requestArr);
	
			$batchItemDetail = array(new soapval('cancelRequestDetails',false,$cancelArr));		
			array_push($batchItems,new soapval('batchItemDetails',false,array('externalID' => $itemArr['batchItemExternalID'],'details' => $batchItemDetail)));		
			
		}
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
					
		$detailsArr = array(
			'batchID' => $batchID,
	 		'batchItemDetailsList' => $batchItems 		
		);
			
	 	$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr
	 	);
		 		 	
		$nusoapResult = $this->doSoapRequest('addBatchItem_Request',$reqParam,false,$client);	
		return $nusoapResult;	
	}
	
	function executeBatch($authentication,$batchID) {	
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
	
		$detailsArr = array(
			'batchID' => $batchID
		);
		
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);		
			
		$nusoapResult = $this->doSoapRequest('executeBatch_Request',$reqParam);	
		return $nusoapResult;	
	}
	
	function getBatchStatus($authentication,$batchID,$externalBatchID,$batchItemsArr) {		
		
			
		
		$client = new nusoap_client($this->SOAP_ENDPOINT);			
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
	
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
			);		
	
		if(!empty($batchItemsArr)) {		
			// Fill itemListArr
			$pos=0;		
		  foreach ($batchItemsArr as $key => $value) {
		    if ($pos==0) {
					$batchItemIDListArr = array(new soapval('batchItemID',false,$value));
		    } else {
					array_push($batchItemIDListArr,new soapval('batchItemID',false,$value));					    	
		    }
		    $pos++;
		  }		
		}
		
	  $detailsArr = array(
			'batchID' => $batchID,
			'externalBatchID' => $externalBatchID,
			'batchItemIDList' => $batchItemIDListArr
		);
		
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);	
	 		
		$nusoapResult = $this->doSoapRequest('getBatchStatus_Request',$reqParam,false,$client);
		return $nusoapResult;
	}
	
	function cancelBatch($authentication,$batchID) {	
		$token = $this->generateToken(AUTH_PROJECT_ID, AUTH_SECRETKEY_ID);
		
		$authenticationArr = array(
			'merchantID' => AUTH_MERCHANT_ID,
			'projectID' => AUTH_PROJECT_ID,
			'token' => $token						
		);		
	
		$detailsArr = array(
			'batchID' => $batchID
		);
		
		$reqParam = array (
			'authentication' => $authenticationArr,
			'details' => $detailsArr 		
	 	);		
			
		$nusoapResult = $this->doSoapRequest('cancelBatch_Request',$reqParam);	
		return $nusoapResult;			
	}
	
	function sendMail($sendEmailTo,$sendEmailFrom,$text) {
		$subject = 'ClickandBuy MMS Event '.date('Y-m-d H:i:s');	
		$body = '
			<html>
				<head>
				  <title>MMS Event</title>
				</head>
				<body>
					------------ new entry, received @ '.date('Y-m-d H:i:s').' -------------------
					<p>'.htmlspecialchars($text,ENT_QUOTES).'</p>
				</body>
			</html>
		';
		
		// Set header
		$header  = 'MIME-Version: 1.0' . "\r\n";
		$header .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
		$header .= 'To: <'.$sendEmailTo.'>' . "\r\n";
		$header .= 'From: <'.$sendEmailFrom.'>' . "\r\n";
	
		// Send mail
		mail($sendEmailTo, $subject, $body, $header);
	}
	
	function getCabSettings($paymentType){
		global $db;
		
		$settings = array();
		$authentication = array();
	  	$settings = $db->db_query("SELECT configuration_key,configuration_value FROM ".TABLE_CONFIGURATION." WHERE configuration_key LIKE 'MODULE_PAYMENT_PI_CLICKANDBUY%'");
	   
	  if($settings->_numOfRows) {
			while (!$settings->EOF) {
		  		$settings->fields[$row['configuration_key']] = $row['configuration_value'];
		  		$settings->MoveNext();
			}	
	
			if ($this->paymentType == 'clickandbuy') {
			  	$authentication['merchantID'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_MERCHANT_ID'];
				$authentication['projectID'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_PROJECT_ID'];
				$authentication['secretKey'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_SECRET_KEY'];
													
			} else {
			  	$authentication['merchantID'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_MERCHANT_ID'];
				$authentication['projectID'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_PROJECT_ID'];
				$authentication['secretKey'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_SECRET_KEY'];													
				$authentication['recDescription'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_DESCRIPTION'];
				$authentication['recNumberOfBillings'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_NUMBER_LIMIT'];
				$authentication['recAmount'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_AMOUNT'];
				$authentication['recCurrency'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_CURRENCY'];
				$authentication['recDateLimit'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_DATE_LIMIT'];
				$authentication['recRevokableByConsumer'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_REVOKABLE'];
				$authentication['initialAmount'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_INITIAL_AMOUNT'];
				$authentication['recUseCase'] = $settings->fields['MODULE_PAYMENT_PI_CLICKANDBUY_RECURRING_SPECIAL_CASE'];
			}		
		}	   			
		return $authentication;
	}
	
	function generateSHash($amount,$currency,$externalID,$secretKey,$additional_1 = '', $additional_2 = ''){
		$shash = md5($amount.$currency.$externalID.$secretKey.$additional_1.$additional_2); 
		return $shash;
	}
	
	function getItemsPartialDelivery() {	
		global $order,$partialDeliveryAmount,$basketAmount,$currency,$initialAmountZero,$shippingCostsText;		
		
		require_once(DIR_FS_INC.'inc.get_products_stock.php');
		
		$itemStock = false;
		$items = array();
		$countPartialDelivery = 0;
	
		//Prepare items from Order Details
		$i = 0;
		foreach($order->products as $key => $value) {
			$item = 'item'.$i;
			$itemID = $value['id'];
			$itemDescription = $value['name'];
			$itemUnitPriceAmount = $value['price'];
			$itemTotalPriceAmount = $value['final_price'];
			$itemQuantity = $value['qty'];
				
			$stockLeft = get_products_stock($itemID) - $itemQuantity;
	    $outOfStock = false;
	
	    if ($stockLeft < 0) {
	      $outOfStock = true;
	    }
	   
			if (!empty($outOfStock)) {
				$partialDeliveryAmount = number_format($partialDeliveryAmount + ($itemUnitPriceAmount * $itemQuantity),2);
	
				$items[$i]['itemType'] = $item.'Text';		
				$items[$i]['textItemDescription'] = 'Partial Delivery: ('.$itemQuantity.' x '.number_format($itemUnitPriceAmount,2).' '.$currency.') '.$itemDescription;				
				$countPartialDelivery++;								
			} else {	
				$itemStock = true; 			
				$items[$i]['itemType'] = $item.'Item';		
				$items[$i]['itemDescription'] = $itemDescription;	
				$items[$i]['itemQuantity'] = $itemQuantity;	
				$items[$i]['itemUnitPriceAmount'] = number_format($itemUnitPriceAmount,2);	
				$items[$i]['itemUnitPriceCurrency'] = $currency;	
				$items[$i]['itemTotalPriceAmount'] = number_format($itemTotalPriceAmount,2);
				$items[$i]['itemTotalPriceCurrency'] = $currency;			
			}						
			$i++;
		}			
	
		if ($i == $countPartialDelivery) {
			$initialAmountZero = true;
		}
		
		if($countPartialDelivery == 0) {
			$partialDeliveryAmount = '0.00';			
		} 	
		
		if($itemStock == false) {
			$partialDeliveryAmount = $basketAmount;			
		} else {
			if(empty($order->info['shipping_cost']) || $order->info['shipping_cost'] == 0) {
				$shippingCost = '0.00';
			}  else {
				$shipping_tax_rate = $this->get_shipping_tax_rate($order);
			
				//Shop has tax class in shipping module add shipping tax to order total 
				if ($shipping_tax_rate > 0) {
					$shipping_tax = round(($order->info ['shipping_cost'] / 100) * $shipping_tax_rate,2);
					$shippingCost = ($order->info['shipping_cost'] + $shipping_tax);				
				} else {
					$shippingCost = $order->info['shipping_cost'];	
				}
			}	
				
			$item = 'item'.$i;
			$itemType = $item.'Item';		
			$items[$i]['itemType'] = $itemType;					
			$items[$i]['itemDescription'] = $shippingCostsText;	
			$items[$i]['itemQuantity'] = 1;	
			$items[$i]['itemUnitPriceAmount'] = number_format($shippingCost,2);	
			$items[$i]['itemUnitPriceCurrency'] = $currency;	
			$items[$i]['itemTotalPriceAmount'] = number_format($shippingCost,2);	
			$items[$i]['itemTotalPriceCurrency'] = $currency;										
		}
		return $items;
	}	
	
	function getConsumerLanguage() {
		global $db;
		
		$lang = $db->db_query("SELECT code FROM ".TABLE_LANGUAGES." WHERE languages_id = '".(int)$_SESSION['languages_id']."'");
		return $lang->fields['code'];
	}
		
	function getItems($currency) {
		global $order,$shippingCostsText;
	
		$items = array();
		$i = 1;
		
		foreach($order->products as $key => $value) {
			$item = 'item'.$i;
			$itemType = $item.'Item';		
			$items[$i]['itemType'] = $itemType;					
			$itemUnitPriceAmount = $value['price'];
			$itemTotalPriceAmount = $value['final_price'];
			$itemQuantity = $value['qty'];
			
			$items[$i]['itemDescription'] = $value['name'];	
			$items[$i]['itemQuantity'] = $itemQuantity;	
			$items[$i]['itemUnitPriceAmount'] = number_format($itemUnitPriceAmount,2);
			$items[$i]['itemUnitPriceCurrency'] = $currency;	
			$items[$i]['itemTotalPriceAmount'] = number_format($itemTotalPriceAmount,2);
			$items[$i]['itemTotalPriceCurrency'] = $currency;						
			$i++;
		}			
		
		if(empty($order->info['shipping_cost']) || $order->info['shipping_cost'] == 0)
			$shippingCost = '0.00';
		else {
			$shipping_tax_rate = $this->get_shipping_tax_rate($order);
			 
			if ($shipping_tax_rate > 0) {
				$shipping_tax = round(($order->info ['shipping_cost'] / 100) * $shipping_tax_rate,2);
				$shippingCost = ($order->info['shipping_cost'] + $shipping_tax);
				
			} else
				$shippingCost = $order->info['shipping_cost'];	
		}	
		
		$item = 'item'.$i;
		$itemType = $item.'Item';		
		$items[$i]['itemType'] = $itemType;					
		$items[$i]['itemDescription'] = $shippingCostsText;	
		$items[$i]['itemQuantity'] = 1;	
		$items[$i]['itemUnitPriceAmount'] = number_format($shippingCost,2);	
		$items[$i]['itemUnitPriceCurrency'] = $currency;	
		$items[$i]['itemTotalPriceAmount'] = number_format($shippingCost,2);	
		$items[$i]['itemTotalPriceCurrency'] = $currency;						
		
		return $items;		
	}	
	
	function redirectError($requestResult) {
		if ($requestResult['error_type'] == 'fault') {	
			$errDescription= $requestResult['values']['detail']['errorDetails']['description'];					
		} else {
			$errDescription = CLICKANDBUY_ERROR_MESSAGE_6;
		}
		$errorMessage = CLICKANDBUY_ERROR_MESSAGE_2.$errDescription.' '.CLICKANDBUY_ERROR_MESSAGE_3;
		redirect(href_link($this->returnURL, 'error_message='.$errorMessage, 'SSL'));
	}	
	
	function showMessageError($message) {
		$message = '<table border="0" width="100%" cellspacing="0" cellpadding="2">
				       	<tr>
							<td class="messageStackError"><img border="0" title="" alt="" src="images/icons/error.gif">'.$message.'</td>
						</tr>
					</table>';			
		return $message;
	}
	
	function showMessageSuccess($message) {	
		$message = '<table border="0" width="100%" cellspacing="0" cellpadding="2">
				       	<tr>
							<td class="messageStackSuccess"><img border="0" title="" alt="" src="images/icons/success.gif">'.$message.'</td>
						</tr>
					</table>';			
		return $message;
	}
	
	function get_shipping_tax_rate($order) {
		if(!empty($order->info['shipping_class'])) {
			$shipping_class_array = explode("_",$order->info['shipping_class']);
			$shipping_class = strtoupper($shipping_class_array[0]);
			
			$const = 'MODULE_SHIPPING_'.$shipping_class.'_TAX_CLASS';
			require_once(DIR_FS_INC.'inc.get_tax_rate.php');
			$shipping_tax_rate = get_tax_rate(constant($const));
			return $shipping_tax_rate;
		}
	}
}
?>